package com.example.controller;

import com.example.utils.PersonalTool;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.*;
import javax.servlet.http.HttpServletRequest;

/**
 * 这里是模拟进件接口
 */
@RestController
public class ApiController {

    //成功
    public static final int SUCCESS = 200;
    //失败
    public static final int ERROR = 400;

    /**
     * 验证渠道是否合法
     * @param sourceCode 渠道码
     * @param accessKey 授权码
     * @return 响应
     */
    protected Map<String, Object> verifySource(String sourceCode, String accessKey) {
        /* 渠道码不能为空 */
        if (sourceCode.isEmpty()) {
            return response(ERROR, new HashMap<>(), "sourceCode is invalid");
        }
        // 检查渠道是否存在
        Map<String, Object> channelInfo = PersonalTool.getChannelInformation(sourceCode);
        if (channelInfo.isEmpty()) {
            return response(ERROR, new HashMap<>(), "sourceCode is not exist");
        }else{
            // 获取数据库中的 accessKey
            String dbAccessKey = (String) channelInfo.get("accessKey");
            // 验证授权码
            if (accessKey.isEmpty()) {
                return response(ERROR, new HashMap<>(), "accessKey is invalid");
            }

            // 比较数据库中的数据是否和传递过来的数据相等
            if (dbAccessKey == null ||!dbAccessKey.equals(accessKey)) {
                return response(ERROR, new HashMap<>(), "channel is invalid");
            }
            // 验证通过，返回成功响应
            return response(SUCCESS, new HashMap<>(), "channel verification passed");
        }
    }

    /**
     * 11位手机号撞库逻辑
     */
    @PostMapping("/filterInfo")
    public Map<String, Object> filterInfo(@RequestBody Map<String, Object> requestBody) {
        // 检查 sourceCode 参数是否合法
        String sourceCode = getStringFromRequest(requestBody, "sourceCode");
        String accessKey = getStringFromRequest(requestBody, "accessKey");
        //验证渠道是否合法
        Map<String, Object> verifyResult = verifySource(sourceCode, accessKey);
        if ((int) verifyResult.get("code") == ERROR) {
            return verifyResult;
        }
        // 检查手机号是否合法
        String phone = getStringFromRequest(requestBody, "phone");
        if (phone.isEmpty()) {
            return response(ERROR, new HashMap<>(), "phone is invalid");
        }

        // 检查手机号长度是否合法
        if (phone.length() != 11) {
            return response(ERROR, new HashMap<>(), "phone length is invalid");
        }

        // 数据已存在
        if (PersonalTool.isPhoneExist(phone)) {
            // 构建一个没有 key 的数组数据
            List<Object> dataList = new ArrayList<>();
            dataList.add(phone);
            return response(ERROR, Map.of("phone", dataList), "phone is exist");
        } else {
            return response(SUCCESS, new HashMap<>(), "phone is not exist");
        }
    }

    // 从请求体中获取字符串参数的辅助方法
    private String getStringFromRequest(Map<String, Object> requestBody, String key) {
        Object value = requestBody.getOrDefault(key, "");
        return value.toString();
    }

    // 公共的响应方法
    private Map<String, Object> response(int code, Map<String, Object> data, String message) {
        Map<String, Object> back = new HashMap<>();
        back.put("code", code);
        back.put("message", message);
        back.put("data", data);
        return back;
    }

    //进件逻辑
    @PostMapping(path = "/publishInfo")
    public Map<String, Object> publishInfo(@RequestBody Map<String, Object> requestBody) {
        // 检查 sourceCode 参数是否合法
        String sourceCode = getStringFromRequest(requestBody, "sourceCode");
        String accessKey = getStringFromRequest(requestBody, "accessKey");
        // 验证渠道是否合法
        Map<String, Object> verifyResult = verifySource(sourceCode, accessKey);
        if ((int) verifyResult.get("code") == ERROR) {
            return verifyResult;
        }

        //验证data参数是否合法
        String data = getStringFromRequest(requestBody, "data");
        if (data.isEmpty() || data.equals("null")) {
            return response(ERROR, new HashMap<>(), "data is empty");
        }

        //获取解密秘钥
        Map<String, Object> channelInfo = PersonalTool.getChannelInformation(sourceCode);
        String key = channelInfo.get("key").toString();
        //对data进行解密，这个是json字符串
        String decode = PersonalTool.xiaoWeiDecrypt(data, key);
        if (decode == null) {
            return response(ERROR, new HashMap<>(), "decode failed");
        }

        //对数据反序列话json数据
        try{
            // 创建 ObjectMapper 实例
            ObjectMapper objectMapper = new ObjectMapper();
            // 将 JSON 字符串反序列化为 Map
            Map<String, Object> map = objectMapper.readValue(decode, Map.class);
            //检测手机号
            String phone = (String) map.get("phone");
            if (phone.isEmpty()) {
                return response(ERROR, new HashMap<>(), "phone is invalid");
            }
            //如果号码已存在，则不可以在进件
            if (PersonalTool.isPhoneExist(phone)) {
                return response(ERROR, new HashMap<>(), "data is exist,publish failed");
            }
            //返回解密后的数据
            return response(SUCCESS, map, "success");
        }catch (Exception e){
            return response(ERROR, new HashMap<>(), e.getMessage());
        }
    }

    //编码加密
    @PostMapping(path = "/mock")
    public  Map<String, Object> mock(@RequestBody Map<String, Object> requestBody) throws Exception{
        Map<String, Object> data = new HashMap<>();
        data.put("phone",getStringFromRequest(requestBody, "phone") );
        data.put("age",getStringFromRequest(requestBody, "age") );
        data.put("city",getStringFromRequest(requestBody, "city") );
        data.put("loan",getStringFromRequest(requestBody, "loan") );
        // 获取渠道，获取加密key
        String sourceCode = getStringFromRequest(requestBody, "sourceCode");
        //返回结果
        String accessKey = getStringFromRequest(requestBody, "accessKey");
        Map<String, Object> channelInfo = PersonalTool.getChannelInformation(sourceCode);
        if (channelInfo.isEmpty()){
            return response(ERROR, new HashMap<>(), "channel info is empty");
        }
        String key = channelInfo.get("key").toString();
        // 使用 Jackson 的 ObjectMapper 将 Map 转换为 JSON 字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(data);
        // 加密
        String encode = PersonalTool.xiaoWeiEncrypt(json, key);
        // 组装返回值
        Map<String, Object> map = new HashMap<>();
        map.put("sourceCode", sourceCode);
        map.put("accessKey", channelInfo.get("accessKey").toString());
        map.put("data", encode);
        //返回结果
        return response(SUCCESS, map, "success");
    }

    //获取客户端ip地址
    @GetMapping(path = "/getClientIp")
    public static Map<String, Object> getClientIp(HttpServletRequest request) throws Exception{
        Map<String, Object> data = new HashMap<>();
        String clientIp = PersonalTool.getClientIp(request);
        data.put("clientIp", clientIp);
        data.put("ip", request.getRemoteAddr());
        data.put("port", request.getRemotePort());
        return data;
    }

    //测试参数绑定获取query参数，同时get请求可以获取body参数的
    @GetMapping(path = "/query")
    public static Map<String, Object> query(@RequestBody Map<String, Object> requestBody,String age)throws Exception{
        Map<String, Object> data = new HashMap<>();
        data.put("name", requestBody.get("name"));
        data.put("age", age);
        return data;
    }
}